"""
1. 实际我们使用 DBeaver 的时候，也是创建一个数据库连接。在这个连接基础之上 实现增删改查操作
2. 为什么要创建一个连接呢？
    ① 节省客户端和服务器的资源 【频繁创建连接和关闭连接 消耗服务器资源】
    ② 从使用角度来说 太麻烦
3. 按照面向对象的 属性使用特点  如果我们把数据库的连接定义为一个属性，当然选择 类属性
    类属性 共享一块内存空间
    对象属性 一个对象一块属性空间，相当于多少个对象多少个空间
"""
import pymysql
class DBTools:
    conn = None #类属性
    @classmethod
    def get_conn(cls):  # ① 实现 数据库的连接
        # 如果 conn 没有值 ，则需要给 conn类属性赋值
        if cls.conn is None:
            cls.conn = pymysql.connect(user="student",  # 用户名
                password="iHRM_student_2022",  # 密码
                host="211.103.136.244",  # 数据库服务器IP
                port=7061,  # 端口号
                database='test_db',  # 使用的数据库名字
                charset='utf8')
        return cls.conn  # 如果 conn 有值，则直接将 conn类属性 返回
    # ② 实现 数据库的连接关闭
    @classmethod
    def close_conn(cls):
        # if cls.conn is not None:
        # 或者
        # cls.conn 有值 转换为布尔值 是真
        if cls.conn:
            # 最好先做 if判断  cls.conn 有值 再执行 连接关闭的操作
            cls.conn.close()
            # 有可能我们会多次 连接创建和关闭 只有把 类属性重置为None
            # 才能为下一次运行 创建连接
            cls.conn = None

    # 定义查询的方法
    @classmethod
    def db_fetch_one(cls,sql):
        try:
            # 1. 获取【调用】数据连接方法
            conn = cls.get_conn()
            # 2. 获取游标对象
            cursor = conn.cursor()
            # 3. 让游标对象执行sql语句
            cursor.execute(sql)
            # 4. 让游标对象获取查询结果
            one = cursor.fetchone()
        except:
            # 如果有异常， one 可能执行不到或者没结果
            one = None
        else:
            cursor.close() # 5. 关闭游标
        return one  # 必须return

    # 定义增删改的方法
    @classmethod
    def db_uid(cls,sql):
        # 因为缩进的原因，造成了编辑器识别变量的问题
        # 其实不设置也没关系，设置了最好
        conn = None
        cursor = None
        try:
            # 1. 获取数据库连接
            conn = cls.get_conn()
            # 2. 创建游标对象
            cursor = conn.cursor()
            # 3. 游标对象执行sql语句【增删改】
            cursor.execute(sql)
            # 4. 提交事务
            conn.commit()
        except:
            # 5. 如果有异常，则应该进行事务回滚
            conn.rollback()
            # 有异常 说明 增删改有问题 返回False
            return False
        else:
            # 6. 关闭游标
            cursor.close()
            # 7. 关闭连接
            cls.close_conn()
            # else 说明 增删改 没有异常 返回True
            return True


if __name__ == '__main__':
    #类名.类方法()
    # 第一次
    DBTools.get_conn()

    sql_update = "update t_book set title='什么狗什么修' where id=1;"
    print(  DBTools.db_uid(sql_update) )

    sql = "select * from t_book;"
    print(  DBTools.db_fetch_one(sql) )

    DBTools.close_conn()
    # print( DBTools.conn )

    # 后边还有可能 要 重新建立连接
    # DBTools.get_conn()
    # DBTools.close_conn()
    # print( DBTools.conn )


